home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 2 / LSD and 17bit Compendium Deluxe - Volume II.iso / a / prog / cprog / ae_doors.lha / AEDoor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-11  |  9.5 KB  |  283 lines

  1. /*
  2.  *   XIM Template for AmiExpress (c) 1993 by Gord Dimitrieff (aka Garindan).
  3.  *   $VER: 1.0 (May 1993)
  4.  *
  5.  *   Adapted from JH_Message/DoorDocs by Joseph Hodge, author of AmiExpress.
  6.  *
  7.  *   -------------------------------------------------------------------------
  8.  *   This file may be freely distributed as long as it remains unmodified.
  9.  *   -------------------------------------------------------------------------
  10.  *
  11.  *   E-Mail Contact: FidoNet#1:250/728.0 (My own system)
  12.  *               or: AmiXNet#416002 (*Not* my own system)
  13.  *               or: gordon.dimitrieff@canrem.com (usenet address)
  14.  *
  15.  *   Postal Contact: Gord Dimitrieff
  16.  *                   120 Dinnick Cres.
  17.  *                   Toronto, Ontario
  18.  *                   M4N 1L8   CANADA
  19.  *
  20.  *   PLEASE contact me if you find any bugs in the logic of this code, or
  21.  *   whatever, so that I may fix the problem for myself.  Please send any
  22.  *   modified versions of this that you think I should know about, etc..
  23.  *
  24.  *   -------------------------------------------------------------------------
  25.  *   DISCLAIMER
  26.  *   -------------------------------------------------------------------------
  27.  *   I in no way, shape or form take any responsibilty for the functionality
  28.  *   of the information presented in this file.  I do not run an AmiExpress
  29.  *   BBS, and therefore can not vouch for its reliablity.  I have done my best
  30.  *   to make it work, but it may not in some cases.  If there are any problems
  31.  *   with these routines, you can ask me for help, but it may be a better idea
  32.  *   to go to somebody who knows more about the whole system than me.
  33.  *   Basically, the only reason I did this was to help me adapt my door program
  34.  *   for use with AmiExpress.  (Unfortunatly, AmiExpress does not support
  35.  *   standard i/o handles through fifo: or anything, so I had to do this.
  36.  *   It's really too bad that this lame way of door support still exists...
  37.  *   Supporting a callback structure would be a much better way..)
  38.  *
  39.  *   -------------------------------------------------------------------------
  40.  *   AN EXPLAINATION...
  41.  *   -------------------------------------------------------------------------
  42.  *   This file was created because of the apparent lack of information
  43.  *   and source code for programming external modules for AmiExpress.
  44.  *
  45.  *   What I have attempted to do here is create a set of 'standard'
  46.  *   routines that can easily be added to existing source, or be used
  47.  *   to create an original program.  These routines have been designed
  48.  *   for easy expansion, so you may add more XIM functions to it, as
  49.  *   well as for easy of use.  These functions will monitor the state of
  50.  *   the XIM port for you, and will call a standard shut-down function
  51.  *   if the user drops carrier, runs out of time, etc.  The code will also
  52.  *   exit safely if it receives a CTRL-C signal.
  53.  *
  54.  *   NB: This file has been designed with OS1.3 compatability in mind.
  55.  *       It makes use of the CreatePort()/DeletePort() functions in amiga.lib,
  56.  *       instead of the new CreateMsgPort()/DeleteMsgPort() in exec..you may
  57.  *       want to change this for your own purposes.
  58.  *
  59.  *
  60.  *   Please look at the main() function in this file to see how exactly the
  61.  *   door protocol should be started up...
  62.  *
  63.  *   -------------------------------------------------------------------------
  64.  *   MODULE DESCRIPTIONS
  65.  *   -------------------------------------------------------------------------
  66.  *   CheckMessage() - Used for sending/receiving messages
  67.  *   PortStart()    - Start up initial door-protocol with AmiExpress
  68.  *                    (allocates memory, creates reply port, etc)
  69.  *                    This returns 0 if everything opens okay, non-zero if not.
  70.  *                    the return code can be used to figure out exactly what
  71.  *                    went wrong, too.
  72.  *   TakeOffEh()    - Shut down door-port and exit (used by ShutDown() )
  73.  *   ShutDown()     - This is automatically called by CheckMessage if anything
  74.  *                    goes wrong.  Insert your save routines here!  This will
  75.  *                    just call TakeOffEh() after calling your save code.
  76.  *   -------------------------------------------------------------------------
  77.  *   GetString()    - Example function for using the input command 
  78.  *   PutString()    - Example function for using the output command
  79.  *   -------------------------------------------------------------------------
  80.  *
  81.  */
  82.  
  83. #include <exec/types.h>
  84. #include <exec/ports.h>
  85. #include <exec/memory.h>
  86. #include <dos/dos.h>
  87. #include <clib/exec_protos.h>
  88. #include <clib/dos_protos.h>
  89. #include <clib/alib_protos.h>
  90. #include <stdio.h>
  91.  
  92. #ifdef LATTICE
  93. int CXBRK(void) {return(0);} /* Disable Lattice CTRL-C handling */
  94. int chkabort(void) {return(0);}
  95. #endif
  96.  
  97. /* Function prototypes: */
  98. int CheckMessage(void);
  99. int PortStart(void);
  100. void TakeOffEh(int code);
  101. void ShutDown(void);
  102.  
  103. void GetString(char text[], int len);
  104. void PutString(char text[], int lf);
  105.  
  106. struct XIM   /* This has been taken directly from JH_Message */
  107. {            /* structure in the doordocs file.  */
  108.  
  109.   struct Message Msg;    /* msg structure */
  110.   char String[200];    /* info buffer */
  111.   int Data;        /* Read/Write & result indicator */
  112.   int Command;        /* Command sent from door. */
  113.   int NodeID;        /* reserved */
  114.   int LineNum;        /* reserved */
  115.   unsigned long signal;    /* reserved */
  116.   struct Process *task;    /* see BB_GETTASK in doordocs */
  117.   APTR Semi;        /* See MULTICOM in doordocs */
  118. };
  119.  
  120. struct MsgPort *DoorControlPort, *DoorReplyPort;
  121. struct XIM *XIM_Msg, *reply;
  122. ULONG usersig, portsig, signals;
  123. STRPTR doorport[30]; /* Portname for AEDoorPort(n) */
  124. int EXIT_FLAG=0; /* This is the global shutdown flag */
  125. char instring[256];
  126.  
  127. void main(int argc, char *argv[])
  128. {
  129. int line_num;
  130.  
  131.     if(argc<2) /* AmiExpress will supply line_num on command line */
  132.     {
  133.         printf("Sorry, %s must be called from AmiExpress.\n",argv[0]);
  134.         exit(0);
  135.     }
  136.  
  137.     line_num=atoi(argv[1]);
  138.  
  139.     /* Don't know what Jon Radoff's problem was.. This works fine.. */
  140.     sprintf((STRPTR)doorport,"AEDoorPort%d",line_num);
  141.  
  142.     if(PortStart()!=0) TakeOffEh(40); /* You must use this before you start! */
  143.  
  144.     /* ..Place your own code in here.. */
  145.     PutString("\fTada!",1);
  146.  
  147.     ShutDown(); /* NEVER quit with exit() as it will cause AmiExpress
  148.                        to wait around forever on you. */
  149. }
  150.  
  151. /**********************************************************************/
  152. /* This function does all of the message passing, and signal checking */
  153. /**********************************************************************/
  154. int CheckMessage(void)
  155. {
  156. int ret=0;
  157.  
  158.     if(DoorControlPort)
  159.     {
  160.         Forbid();
  161.         PutMsg(DoorControlPort, (struct Message *)XIM_Msg);
  162.         Permit();
  163.  
  164.         signals = Wait(usersig|portsig);
  165.         if(signals & portsig)
  166.         {
  167.             if(reply = (struct XIM_Msg *) GetMsg(DoorReplyPort))
  168.             {
  169.                 strcpy(instring,XIM_Msg->String);
  170.                 if(XIM_Msg->Data == -1) EXIT_FLAG=1;
  171.                 ret=XIM_Msg->Data;
  172.             }
  173.         }
  174.         if(signals & usersig) EXIT_FLAG=1; /* CTRL-C was received */
  175.     }
  176.     else
  177.     {
  178.         printf("Error! Can no longer locate doorport!!\n");
  179.         EXIT_FLAG=1;
  180.     }
  181.     if(EXIT_FLAG) ShutDown();
  182.     return(ret);
  183. }
  184.  
  185. /*****************************************************************************/
  186.  
  187. int PortStart(void)
  188. {
  189. int error=0;
  190.  
  191.     if(DoorReplyPort = CreatePort(0,0))
  192.     {
  193.         portsig = 1<<DoorReplyPort->mp_SigBit; /* setup signal bits */
  194.         usersig = SIGBREAKF_CTRL_C;
  195.  
  196.         if(XIM_Msg = (struct XIM *) AllocMem(sizeof(struct XIM), MEMF_PUBLIC |MEMF_CLEAR))
  197.         {
  198.             /* Setup stuff for exec.. */
  199.             XIM_Msg->Msg.mn_Node.ln_Type = NT_MESSAGE;
  200.             XIM_Msg->Msg.mn_Length = sizeof(struct XIM);
  201.             XIM_Msg->Msg.mn_ReplyPort = DoorReplyPort;
  202.  
  203.             XIM_Msg->Command = 1; /* Register Door with AmiExpress */
  204.  
  205.             Forbid();
  206.             DoorControlPort = FindPort(doorport);
  207.             Permit();
  208.  
  209.             if(DoorControlPort==NULL)
  210.             {
  211.                 printf("Can't find doorport \"%s\"\n",doorport);
  212.                 error=3;
  213.             }
  214.             else CheckMessage();
  215.         }
  216.         else
  217.         {
  218.             printf("Can't allocate memory for XIM Message Structure!\n");
  219.             error=2;
  220.         }
  221.     }
  222.     else
  223.     {
  224.         printf("Can't setup reply port!\n");
  225.         error=1;
  226.     }
  227.  
  228. return(error);
  229. }
  230.  
  231. void TakeOffEh(int code) /* Notify AmiExpress of shutdown, and then exit safely */
  232. {
  233.     XIM_Msg->Command=2;
  234.     if(DoorControlPort) CheckMessage();
  235.  
  236.     if(XIM_Msg) FreeMem(XIM_Msg, sizeof(struct XIM));
  237.     if(DoorReplyPort) DeletePort(DoorReplyPort);
  238.     exit(code);
  239. }
  240.  
  241. /*****************************************************************************\
  242.  This is the start of the general routines that you will probably want to use.
  243.  Only two other functions are provided in addition to the ShutDown() funciton,
  244.  for the purpose of examples:
  245.  
  246.  To use the other XIM commands available, look up the Msg->Command/Data fields
  247.  from the doordocs file, set them up for the XIM_Msg struct, and then
  248.  CheckMessage() it.  The contents of XIM_Msg->String will be copied into the
  249.  global instring[] for you when the command returns, and CheckMessage() will
  250.  return the contents of XIM_Msg->Data.  (Note that 'XIM_Msg' is simply called
  251.  'Msg' in the doordocs file.
  252.  
  253. \*****************************************************************************/
  254.  
  255. void ShutDown(void)
  256. {
  257.     /* This routine will be call automatically by CheckMessage if
  258.            AmiExpress says to shut down, or if it receives a CTRL-C signal.
  259.            This allows you to save any data before shutdown.
  260.  
  261.            IF YOU HAVE ANYTHING TO SAVE, DO IT HERE!!  THIS NEVER RETURNS!
  262.     */
  263.  
  264.     TakeOffEh(0);
  265. }
  266.  
  267. void GetString(char text[], int len)
  268. {
  269.     XIM_Msg->Command=0;
  270.     XIM_Msg->Data=len;
  271.     strcpy(XIM_Msg->String,text);
  272.     CheckMessage(); /* the returned string will be found in instring[] */
  273. }
  274.  
  275. void PutString(char text[], int lf)
  276. {
  277.     XIM_Msg->Command=4;
  278.     XIM_Msg->Data=lf;
  279.     strcpy(XIM_Msg->String,text);
  280.     CheckMessage();
  281. }
  282.  
  283.